using System.IO;
using Xunit;

namespace CodePlex.TfsLibrary.Utility
{
    public class CompressionUtilTest
    {
        static readonly byte[] largeData = new byte[20000];
        static readonly byte[] smallData = new byte[1];

        [Fact]
        public void GZipIncompatibleWithDeflate()
        {
            Pair<byte[], CompressionType> result = CompressionUtil.Compress(largeData, CompressionType.GZip);

            Assert.Throws<InvalidDataException>(delegate
                                                {
                                                    CompressionUtil.Decompress(result.Left, CompressionType.Deflate);
                                                });
        }

        [Fact]
        public void InvalidDeflatedData()
        {
            Assert.Throws<InvalidDataException>(delegate
                                                {
                                                    CompressionUtil.Decompress(largeData, CompressionType.Deflate);
                                                });
        }

        [Fact]
        public void InvalidGzippedData()
        {
            Assert.Throws<InvalidDataException>(delegate
                                                {
                                                    CompressionUtil.Decompress(largeData, CompressionType.GZip);
                                                });
        }

        [Fact]
        public void LargeDataDeflates()
        {
            Pair<byte[], CompressionType> result = CompressionUtil.Compress(largeData, CompressionType.Deflate);

            Assert.Equal(CompressionType.Deflate, result.Right);
            Assert.NotSame(largeData, result.Left);
            Assert.True(result.Left.Length < largeData.Length);
            Assert.Equal(largeData, CompressionUtil.Decompress(result.Left, CompressionType.Deflate));
        }

        [Fact]
        public void LargeDataGZips()
        {
            Pair<byte[], CompressionType> result = CompressionUtil.Compress(largeData, CompressionType.GZip);

            Assert.Equal(CompressionType.GZip, result.Right);
            Assert.NotSame(largeData, result.Left);
            Assert.True(result.Left.Length < largeData.Length);
            Assert.Equal(largeData, CompressionUtil.Decompress(result.Left, CompressionType.GZip));
        }

        [Fact]
        public void PassThroughCompress()
        {
            Pair<byte[], CompressionType> result = CompressionUtil.Compress(largeData, CompressionType.None);

            Assert.Equal(CompressionType.None, result.Right);
            Assert.Same(largeData, result.Left);
        }

        [Fact]
        public void PassThroughDecompress()
        {
            byte[] result = CompressionUtil.Decompress(largeData, CompressionType.None);

            Assert.Same(largeData, result);
        }

        [Fact]
        public void SmallDataWillNotDeflate()
        {
            Pair<byte[], CompressionType> result = CompressionUtil.Compress(smallData, CompressionType.Deflate);

            Assert.Equal(CompressionType.None, result.Right);
            Assert.Same(smallData, result.Left);
        }

        [Fact]
        public void SmallDataWillNotGzip()
        {
            Pair<byte[], CompressionType> result = CompressionUtil.Compress(smallData, CompressionType.GZip);

            Assert.Equal(CompressionType.None, result.Right);
            Assert.Same(smallData, result.Left);
        }
    }
}